Imports System.Text

Namespace Core.Modules


    Public Class ProductTranslator
        Inherits Translator

        Public Overloads Sub StatusMessage(ByVal msg As String)
            wln(msg)
            MyBase.StatusMessage(msg)
        End Sub

        Private Sub wln(ByVal message As String)
            Logging.WriteLine(message)
        End Sub

        Public Overrides Function Export() As Boolean
            Dim result As Boolean = True


            StatusMessage("Logging Into Web Store")
            Dim t As New BVweb.AuthenticationToken
            If WebServiceUtilities.Login(t) = False Then

                MsgBox("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                Return False
            Else
                Logging.WriteLine("Successfully logged into store")
            End If

            StatusMessage("Getting List of Products")
            Dim svc As New BVweb.WebServices3
            svc.Url = Helpers.FullServiceUrl

            Dim rows As Integer = 0

            Dim criteria As New BVweb.ProductSearchCriteria
            InitializeCriteria(criteria)

            ' Bug in SP1 prevents us from using "FindAll" so this hack gets everything within reason
            Dim prods() As BVweb.Product = svc.Catalog_InternalProduct_FindByCriteria_WithPaging(t, criteria, "-1", 500000, rows)            

            If prods IsNot Nothing Then
                StatusMessage("Exporting Products")
                If prods.Length < 1 Then
                    StatusMessage("No Products were Returned")
                    Return False
              
                End If


                RenderExport(prods, t, svc)
            Else
                MsgBox("No products were returned from the store. Unable to export.")
                Return False
            End If

            Return result
        End Function

        Public Sub InitializeCriteria(ByRef criteria As BVweb.ProductSearchCriteria)
            criteria.Keyword = String.Empty
            criteria.ManufacturerId = String.Empty
            criteria.VendorId = String.Empty
            criteria.ParentId = String.Empty
            criteria.Status = BVweb.ProductStatus.NotSet
            criteria.InventoryStatus = BVweb.ProductInventoryStatus.NotSet
            criteria.ProductTypeId = String.Empty
            criteria.CategoryId = String.Empty
            criteria.NotCategoryId = String.Empty
            criteria.MinPrice = -1D
            criteria.MaxPrice = -1D
            'criteria.CreatedAfter = Nothing
            criteria.KeywordIsExact = False
            criteria.LastXNumberOfItemsAddedToStore = -1
            criteria.ItemsAddedInLastXDays = -1
            criteria.SortOrder = BVweb.ProductSearchCriteriaSortOrder.Ascending
            criteria.SortBy = BVweb.ProductSearchCriteriaSortBy.ProductName
            criteria.ChoicesAndChoiceOptions = Nothing            
            'criteria.showProductCombinations = False
            criteria.SpecialProductTypeOne = BVweb.SpecialProductTypes1.NotSet
            criteria.SpecialProductTypeTwo = BVweb.SpecialProductTypes1.NotSet
            'criteria.displayInactiveProducts = False
            criteria.CustomProperties = Nothing
        End Sub

        Public Overrides Function Import(ByVal lines() As String, ByVal cols() As MappedColumn) As Boolean
            Dim result = True

            Logging.WriteLine("Logging into store for Import...")
            StatusMessage("Logging Into Store for Import...")
            Dim t As New BVweb.AuthenticationToken
            If WebServiceUtilities.Login(t) = False Then
                Logging.WriteLine("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                MsgBox("Login to store failed with username " & My.Settings.StoreUsername & ". Check your settings and try again.")
                Return False
            End If
            Dim svc As New BVweb.WebServices3
            svc.Url = Helpers.FullServiceUrl

            Logging.WriteLine("Processing " & lines.Length & " lines")
            For i As Integer = 1 To lines.Length - 1
                StatusMessage("Importing Item " & (i + 1))
                ImportItem(lines(i), cols, svc, t)
            Next

            Logging.WriteLine("Finished with Import!")
            StatusMessage("Finished with Import!")

            Return result
        End Function

        Private Sub ImportItem(ByVal l As String, ByVal cols() As MappedColumn, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            Dim data() As String = l.Split(vbTab)
            If data IsNot Nothing Then
                Try

                    Dim updateMode As Boolean = False
                    Dim bvin As String = data(0).Trim
                    If bvin = "new" Then
                        bvin = String.Empty
                    End If

                    Dim p As New BVweb.InternalProduct
                    InitProduct(p)

                    If bvin <> String.Empty Then
                        ' we're updating
                        Dim tempP As BVweb.Product = svc.Catalog_InternalProduct_FindByBvin(t, bvin)
                        If tempP IsNot Nothing Then
                            If tempP.Bvin = bvin Then
                                updateMode = True
                                p = tempP.GlobalProduct
                                Select Case p.SpecialProductType
                                    Case BVweb.SpecialProductTypes.ArbitrarilyPricedGiftCertificate
                                        ' do nothing
                                    Case BVweb.SpecialProductTypes.GiftCertificate
                                        ' do nothing
                                    Case BVweb.SpecialProductTypes.Normal
                                        ' do nothing
                                    Case Else
                                        p.SpecialProductType = BVweb.SpecialProductTypes.Normal
                                End Select
                            End If
                        End If
                    End If

                    For i As Integer = 0 To data.Length - 1
                        ParseField(data(i), cols(i).ColumnName, p)
                    Next


                    Dim result As Boolean = False
                    StatusMessage("Saving Product " & p.ProductName)

                    If updateMode Then
                        Select Case p.SpecialProductType
                            Case BVweb.SpecialProductTypes.ArbitrarilyPricedGiftCertificate
                                ' do nothing
                            Case BVweb.SpecialProductTypes.GiftCertificate
                                ' do nothing
                            Case BVweb.SpecialProductTypes.Normal
                                p.SpecialProductType = BVweb.SpecialProductTypes.Normal
                            Case Else
                                p.SpecialProductType = BVweb.SpecialProductTypes.Normal
                        End Select
                        Dim tempP As New BVweb.Product

                        CopyAttributesToProduct(tempP, p)
                        UpdateCustomURL(tempP, svc, t)
                        tempP.Saved = True
                        tempP.GlobalProduct.Saved = True
                        tempP.SpecialProductType = p.SpecialProductType
                        tempP.GlobalProduct.SpecialProductType = p.SpecialProductType
                        result = svc.Catalog_InternalProduct_Update(t, tempP)
                    Else
                        p.Bvin = System.Guid.NewGuid.ToString()
                        p.Saved = False
                        result = svc.Catalog_InternalProduct_Commit(t, p)
                        Dim tempP As New BVweb.Product
                        CopyAttributesToProduct(tempP, p)
                        AddCustomURL(tempP, svc, t)
                    End If



                    If result Then
                        If updateMode Then
                            Logging.WriteLine("Updated Product " & p.Sku & ":" & p.ProductName)
                        Else
                            Logging.WriteLine("Created Product " & p.Sku & ":" & p.ProductName)
                        End If

                        ' Check for categories and additional images
                        For q As Integer = 0 To cols.Length - 1
                            Select Case cols(q).ColumnName
                                Case "additionalimages"
                                    Dim rawImageData As String = data(q)
                                    rawImageData = MapperUtils.TrimQuotes(rawImageData)
                                    If rawImageData <> String.Empty Then


                                        Dim rawImages() As String = rawImageData.Split("|")
                                        If rawImages IsNot Nothing Then
                                            Logging.WriteLine("Adding Images...")
                                            For index As Integer = 0 To rawImages.Length - 1
                                                Dim tempImg As New ProductImageData()
                                                tempImg.FromString(rawImages(index))
                                                Dim tempImg2 As BVweb.ProductImage = tempImg.ToImage
                                                If tempImg2 IsNot Nothing Then
                                                    tempImg2.ProductId = p.Bvin

                                                    If tempImg2.Bvin <> String.Empty Then

                                                        If svc.Catalog_ProductImage_Update(t, tempImg2) Then
                                                            Logging.WriteLine("Updated Image: " & tempImg.FileName)
                                                        Else
                                                            Logging.WriteLine("Failed to update image: " & tempImg.FileName)
                                                        End If
                                                    Else
                                                        If svc.Catalog_ProductImage_Insert(t, tempImg2) Then
                                                            Logging.WriteLine("Added Image: " & tempImg.FileName)
                                                        Else
                                                            Logging.WriteLine("Failed to add image: " & tempImg.FileName)
                                                        End If
                                                    End If

                                                End If
                                            Next
                                        End If
                                    End If
                                Case "categories"
                                    Dim categoryData As String = data(q)
                                    categoryData = MapperUtils.TrimQuotes(categoryData)
                                    If categoryData <> String.Empty Then


                                        Dim cats() As String = categoryData.Split(",")
                                        If cats IsNot Nothing Then
                                            Logging.WriteLine("Assigning to Categories...")
                                            For catIndex As Integer = 0 To cats.Length - 1
                                                If svc.Catalog_Category_AddProduct(t, cats(catIndex), p.Bvin) Then
                                                    Logging.WriteLine("Added to category id " & cats(catIndex))
                                                Else
                                                    Logging.WriteLine("Failed to add to category id " & cats(catIndex))
                                                End If
                                            Next
                                        End If
                                    End If
                            End Select
                        Next
                    Else
                        If updateMode Then
                            Logging.WriteLine("ERROR: Failed to update Product " & p.Sku & ":" & p.ProductName)
                        Else
                            Logging.WriteLine("ERROR: Failed to create Product " & p.Sku & ":" & p.ProductName)
                        End If
                    End If
                Catch ex As Exception
                    Logging.WriteLine("EXCEPTION: From Import Item: " & ex.Message & "|" & ex.StackTrace)
                End Try
            End If
        End Sub

        Private Sub UpdateCustomURL(ByRef p As BVweb.Product, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            If p.RewriteUrl.Trim IsNot Nothing Then
                Dim cURL As BVweb.CustomUrl = svc.Content_CustomUrl_FindBySystemData(t, p.Bvin.ToString)
                If cURL.RequestedUrl <> p.RewriteUrl Then
                    cURL.RequestedUrl = p.RewriteUrl
                    svc.Content_CustomUrl_Update(t, cURL)
                End If
            End If
        End Sub

        Private Sub AddCustomURL(ByRef p As BVweb.Product, ByRef svc As BVweb.WebServices3, ByRef t As BVweb.AuthenticationToken)
            If p.RewriteUrl.Trim IsNot Nothing Then
                Dim cURL As BVweb.CustomUrl = New BVweb.CustomUrl
                cURL.Bvin = System.Guid.NewGuid.ToString()
                cURL.SystemUrl = True
                cURL.SystemData = p.Bvin
                cURL.RequestedUrl = p.RewriteUrl.Trim
                cURL.RedirectToUrl = svc.Utilities_UrlRewriter_BuildPhysicalUrlForProduct(t, p, "")
                svc.Content_CustomUrl_Insert(t, cURL)
            End If
        End Sub

        Private Sub CopyAttributesToProduct(ByRef result As BVweb.Product, ByRef iprod As BVweb.InternalProduct)
            'result.AdditionalImages
            result.GlobalProduct = New BVweb.InternalProduct
            result.GlobalProduct.Bvin = iprod.Bvin
            result.GlobalProduct.CreationDate = iprod.CreationDate
            result.GlobalProduct.ExtraShipFee = iprod.ExtraShipFee
            result.GlobalProduct.GiftCertificateCodePattern = iprod.GiftCertificateCodePattern
            result.GlobalProduct.GiftWrapAllowed = iprod.GiftWrapAllowed
            result.GlobalProduct.ImageFileMedium = iprod.ImageFileMedium
            result.GlobalProduct.ImageFileSmall = iprod.ImageFileSmall
            result.GlobalProduct.Keywords = iprod.Keywords
            result.GlobalProduct.LastUpdated = iprod.LastUpdated
            result.GlobalProduct.ListPrice = iprod.ListPrice
            result.GlobalProduct.LongDescription = iprod.LongDescription
            result.GlobalProduct.ManufacturerId = iprod.ManufacturerId
            result.GlobalProduct.MetaDescription = iprod.MetaDescription
            result.GlobalProduct.MetaKeywords = iprod.MetaKeywords
            result.GlobalProduct.MetaTitle = iprod.MetaTitle
            result.GlobalProduct.MinimumQty = iprod.MinimumQty
            result.GlobalProduct.NonShipping = iprod.NonShipping
            result.GlobalProduct.ParentId = iprod.ParentId
            result.GlobalProduct.PreTransformLongDescription = iprod.PreTransformLongDescription
            result.GlobalProduct.ProductName = iprod.ProductName
            result.GlobalProduct.ProductTypeId = iprod.ProductTypeId
            result.GlobalProduct.ShippingHeight = iprod.ShippingHeight
            result.GlobalProduct.ShippingLength = iprod.ShippingLength
            result.GlobalProduct.ShippingMode = iprod.ShippingMode
            result.GlobalProduct.ShippingWeight = iprod.ShippingWeight
            result.GlobalProduct.ShippingWidth = iprod.ShippingWidth
            result.GlobalProduct.ShipSeparately = iprod.ShipSeparately
            result.GlobalProduct.ShortDescription = iprod.ShortDescription
            result.GlobalProduct.SiteCost = iprod.SiteCost
            result.GlobalProduct.SitePrice = iprod.SitePrice
            result.GlobalProduct.Sku = iprod.Sku
            result.GlobalProduct.SpecialProductType = iprod.SpecialProductType
            result.GlobalProduct.Status = iprod.Status
            result.GlobalProduct.TaxClass = iprod.TaxClass
            result.GlobalProduct.TaxExempt = iprod.TaxExempt
            result.GlobalProduct.TemplateName = iprod.TemplateName
            result.GlobalProduct.TrackInventory = iprod.TrackInventory
            result.GlobalProduct.VariantDisplay = iprod.VariantDisplay
            result.GlobalProduct.VendorId = iprod.VendorId
            result.GlobalProduct.SitePriceOverrideText = iprod.SitePriceOverrideText
            result.GlobalProduct.RewriteUrl = iprod.RewriteUrl
            result.GlobalProduct.PreContentColumnId = iprod.PreContentColumnId
            result.GlobalProduct.PostContentColumnId = iprod.PostContentColumnId
            result.GlobalProduct.ProductURL = iprod.ProductURL

            result.Bvin = iprod.Bvin
            result.CreationDate = iprod.CreationDate
            result.ExtraShipFee = iprod.ExtraShipFee
            result.GiftCertificateCodePattern = iprod.GiftCertificateCodePattern
            result.GiftWrapAllowed = iprod.GiftWrapAllowed
            result.ImageFileMedium = iprod.ImageFileMedium
            result.ImageFileSmall = iprod.ImageFileSmall
            result.Keywords = iprod.Keywords
            result.LastUpdated = iprod.LastUpdated
            result.ListPrice = iprod.ListPrice
            result.LongDescription = iprod.LongDescription
            result.ManufacturerId = iprod.ManufacturerId
            result.MetaDescription = iprod.MetaDescription
            result.MetaKeywords = iprod.MetaKeywords
            result.MetaTitle = iprod.MetaTitle
            result.MinimumQty = iprod.MinimumQty
            result.NonShipping = iprod.NonShipping
            result.ParentId = iprod.ParentId
            result.PreTransformLongDescription = iprod.PreTransformLongDescription
            result.ProductName = iprod.ProductName
            result.ProductTypeId = iprod.ProductTypeId
            result.ShippingHeight = iprod.ShippingHeight
            result.ShippingLength = iprod.ShippingLength
            result.ShippingMode = iprod.ShippingMode
            result.ShippingWeight = iprod.ShippingWeight
            result.ShippingWidth = iprod.ShippingWidth
            result.ShipSeparately = iprod.ShipSeparately
            result.ShortDescription = iprod.ShortDescription
            result.SiteCost = iprod.SiteCost
            result.SitePrice = iprod.SitePrice
            result.Sku = iprod.Sku
            result.SpecialProductType = iprod.SpecialProductType
            result.Status = iprod.Status
            result.TaxClass = iprod.TaxClass
            result.TaxExempt = iprod.TaxExempt
            result.TemplateName = iprod.TemplateName
            result.TrackInventory = iprod.TrackInventory
            result.VariantDisplay = iprod.VariantDisplay
            result.VendorId = iprod.VendorId
            result.SitePriceOverrideText = iprod.SitePriceOverrideText
            result.RewriteUrl = iprod.RewriteUrl
            result.PreContentColumnId = iprod.PreContentColumnId
            result.PostContentColumnId = iprod.PostContentColumnId
            result.ProductURL = iprod.ProductURL
            '          AdditionalImages	Nothing	BvcImportTool.BVweb.ProductImage()
            'Categories	Nothing	String()
            'ChoiceCombinations	Nothing	BvcImportTool.BVweb.ProductChoiceCombination()
            'PostContentColumnId	Nothing	String
            'PreContentColumnId	Nothing	String
            'ProductURL	Nothing	String
            'Reviews	Nothing	BvcImportTool.BVweb.ProductReview()
            'RewriteUrl	Nothing	String
            'SitePriceOverrideText	Nothing	String
        End Sub

        Private Sub InitProduct(ByRef result As BVweb.InternalProduct)
            'result.AdditionalImages
            result.Bvin = String.Empty
            result.CreationDate = DateTime.Now
            result.ExtraShipFee = 0D
            result.GiftCertificateCodePattern = String.Empty
            result.GiftWrapAllowed = True
            result.ImageFileMedium = String.Empty
            result.ImageFileSmall = String.Empty
            result.Keywords = String.Empty
            result.LastUpdated = DateTime.Now
            result.ListPrice = 0D
            result.LongDescription = String.Empty
            result.ManufacturerId = String.Empty
            result.MetaDescription = String.Empty
            result.MetaKeywords = String.Empty
            result.MetaTitle = String.Empty
            result.MinimumQty = 0
            result.NonShipping = False
            result.ParentId = String.Empty
            result.PreTransformLongDescription = String.Empty
            result.ProductName = String.Empty
            result.ProductTypeId = String.Empty
            result.ShippingHeight = 0D
            result.ShippingLength = 0D
            result.ShippingMode = BVweb.ShippingMode.ShipFromSite
            result.ShippingWeight = 0D
            result.ShippingWidth = 0D
            result.ShipSeparately = False
            result.ShortDescription = String.Empty
            result.SiteCost = 0D
            result.SitePrice = 0D
            result.Sku = String.Empty
            result.SpecialProductType = BVweb.SpecialProductTypes.Normal
            result.Status = BVweb.ProductStatus.Active
            result.TaxClass = String.Empty
            result.TaxExempt = False
            result.TemplateName = "Bvc5"
            result.TrackInventory = False
            result.VariantDisplay = BVweb.VariantDisplayMode.IndividualFields
            result.VendorId = String.Empty

            result.SitePriceOverrideText = String.Empty
            result.RewriteUrl = String.Empty
            result.PreContentColumnId = String.Empty
            result.PostContentColumnId = String.Empty
            result.ProductURL = String.Empty

            '          AdditionalImages	Nothing	BvcImportTool.BVweb.ProductImage()
            'Categories	Nothing	String()
            'ChoiceCombinations	Nothing	BvcImportTool.BVweb.ProductChoiceCombination()
            'PostContentColumnId	Nothing	String
            'PreContentColumnId	Nothing	String
            'ProductURL	Nothing	String
            'Reviews	Nothing	BvcImportTool.BVweb.ProductReview()
            'RewriteUrl	Nothing	String
            'SitePriceOverrideText	Nothing	String


        End Sub

        Private Sub ParseField(ByVal fieldData As String, ByVal columnName As String, ByRef p As BVweb.InternalProduct)
            Select Case columnName

                Case "parentid"
                    p.ParentId = MapperUtils.ParseFieldString(fieldData, p.ParentId)
                Case "status"
                    p.Status = ParseFieldStatus(fieldData, p.Status)
                Case "sku"
                    p.Sku = ScrubSku(MapperUtils.ParseFieldString(fieldData, p.Sku))
                Case "productname"
                    p.ProductName = MapperUtils.ParseFieldString(fieldData, p.ProductName)
                Case "producttypeid"
                    p.ProductTypeId = MapperUtils.ParseFieldString(fieldData, p.ProductTypeId)
                Case "siteprice"
                    p.SitePrice = MapperUtils.ParseFieldDecimal(fieldData, p.SitePrice)
                Case "sitepriceoverridetext"
                    p.SitePriceOverrideText = MapperUtils.ParseFieldString(fieldData, p.SitePriceOverrideText)
                Case "listprice"
                    p.ListPrice = MapperUtils.ParseFieldDecimal(fieldData, p.ListPrice)
                Case "sitecost"
                    p.SiteCost = MapperUtils.ParseFieldDecimal(fieldData, p.SiteCost)
                Case "shortdescription"
                    p.ShortDescription = MapperUtils.ParseFieldString(fieldData, p.ShortDescription)
                Case "longdescription"
                    p.LongDescription = MapperUtils.ParseFieldString(fieldData, p.LongDescription)
                Case "imagefilesmall"
                    p.ImageFileSmall = MapperUtils.ParseFieldString(fieldData, p.ImageFileSmall)
                Case "imagefilemedium"
                    p.ImageFileMedium = MapperUtils.ParseFieldString(fieldData, p.ImageFileMedium)
                    'case "additionalimages"
                    '    p.additionalimages = parsefieldimages(fielddata, p.additionalimages)
                    'case "categories"
                    '    p.categories = parsefieldcategories(fielddata, p.categories)
                Case "keywords"
                    p.Keywords = MapperUtils.ParseFieldString(fieldData, p.Keywords)
                Case "metatitle"
                    p.MetaTitle = MapperUtils.ParseFieldString(fieldData, p.MetaTitle)
                Case "metadescription"
                    p.MetaDescription = MapperUtils.ParseFieldString(fieldData, p.MetaDescription)
                Case "metakeywords"
                    p.MetaKeywords = MapperUtils.ParseFieldString(fieldData, p.MetaKeywords)
                Case "manufacturerid"
                    p.ManufacturerId = MapperUtils.ParseFieldString(fieldData, p.ManufacturerId)
                Case "vendorid"
                    p.VendorId = MapperUtils.ParseFieldString(fieldData, p.VendorId)
                Case "rewriteurl"
                    p.RewriteUrl = MapperUtils.ParseFieldString(fieldData, p.RewriteUrl)
                Case "minimumqty"
                    p.MinimumQty = MapperUtils.ParseFieldInteger(fieldData, p.MinimumQty)
                Case "postcontentcolumnid"
                    p.PostContentColumnId = MapperUtils.ParseFieldString(fieldData, p.PostContentColumnId)
                Case "precontentcolumnid"
                    p.PreContentColumnId = MapperUtils.ParseFieldString(fieldData, p.PreContentColumnId)
                Case "pretransformlongdescription"
                    p.PreTransformLongDescription = MapperUtils.ParseFieldString(fieldData, p.PreTransformLongDescription)
                Case "nonshipping"
                    p.NonShipping = MapperUtils.ParseFieldBoolean(fieldData, p.NonShipping)
                Case "shippingheight"
                    p.ShippingHeight = MapperUtils.ParseFieldDecimal(fieldData, p.ShippingHeight)
                Case "shippinglength"
                    p.ShippingLength = MapperUtils.ParseFieldDecimal(fieldData, p.ShippingLength)
                Case "shippingmode"
                    p.ShippingMode = ParseFieldShippingMode(fieldData, p.ShippingMode)
                Case "shippingweight"
                    p.ShippingWeight = MapperUtils.ParseFieldDecimal(fieldData, p.ShippingWeight)
                Case "shippingwidth"
                    p.ShippingWidth = MapperUtils.ParseFieldDecimal(fieldData, p.ShippingWidth)
                Case "shipseparately"
                    p.ShipSeparately = MapperUtils.ParseFieldBoolean(fieldData, p.ShipSeparately)
                Case "specialproductype"
                    p.SpecialProductType = ParseSpecialProductType(fieldData, p.SpecialProductType)
                Case "extrashipfee"
                    p.ExtraShipFee = MapperUtils.ParseFieldDecimal(fieldData, p.ExtraShipFee)
                Case "taxclass"
                    p.TaxClass = MapperUtils.ParseFieldString(fieldData, p.TaxClass)
                Case "taxexempt"
                    p.TaxExempt = MapperUtils.ParseFieldBoolean(fieldData, p.TaxExempt)
                Case "templatename"
                    p.TemplateName = MapperUtils.ParseFieldString(fieldData, p.TemplateName)
                Case "trackinventory"
                    p.TrackInventory = MapperUtils.ParseFieldBoolean(fieldData, p.TrackInventory)
            End Select
        End Sub

        Private Function ParseFieldStatus(ByVal input As String, ByVal originalData As BVweb.ProductStatus) As BVweb.ProductStatus
            Dim data As String = MapperUtils.ParseFieldString(input, SafeStatus(originalData))
            Dim result As BVweb.ProductStatus = originalData
            Select Case data.ToLower
                Case "active", "1", "a"
                    result = BVweb.ProductStatus.Active
                Case "disabled", "0", "d"
                    result = BVweb.ProductStatus.Disabled
            End Select
            Return result
        End Function

        Private Function ParseFieldShippingMode(ByVal input As String, ByVal originalData As BVweb.ShippingMode) As BVweb.ShippingMode
            Dim data As String = MapperUtils.ParseFieldString(input, SafeShippingMode(originalData))
            Dim result As BVweb.ShippingMode = originalData
            Select Case data.ToLower
                Case "manufacturer", "m"
                    result = BVweb.ShippingMode.ShipFromManufacturer
                Case "site", "s"
                    result = BVweb.ShippingMode.ShipFromSite
                Case "vendor", "v"
                    result = BVweb.ShippingMode.ShipFromVendor
            End Select
            Return result
        End Function

        Private Function ParseSpecialProductType(ByVal input As String, ByVal originalData As BVweb.SpecialProductTypes) As BVweb.SpecialProductTypes
            Dim result As BVweb.SpecialProductTypes = BVweb.SpecialProductTypes.Normal
            Dim data As String = MapperUtils.ParseFieldString(input, SafeSpecialProductType(originalData))
            Select Case data.ToLower
                Case "n", "normal", "none"
                    result = BVweb.SpecialProductTypes.Normal
                Case "g", "gift", "giftcertificate"
                    result = BVweb.SpecialProductTypes.GiftCertificate
                Case "v", "variablegift", "arbitrarygiftcertificate", "a", "arbitrary", "arbitrarilypricedgiftcertificate"
                    result = BVweb.SpecialProductTypes.ArbitrarilyPricedGiftCertificate
            End Select
            Return result
        End Function

        Private Sub RenderExport(ByVal data() As BVweb.Product, ByRef t As BVweb.AuthenticationToken, ByRef svc As BVweb.WebServices3)
            Dim sb As New StringBuilder

            WriteHeaders(sb)
            For i As Integer = 0 To data.Length - 1
                StatusMessage("Exporting Product " & (i + 1) & " of " & data.Length)
                WriteItem(data(i), sb, t, svc)
            Next

            Dim v As New ExportView
            v.OutputText = sb.ToString
            v.ShowDialog()
            v.Dispose()
        End Sub

        Private Sub WriteHeaders(ByRef sb As StringBuilder)
            StatusMessage("Writing Headers")

            sb.Append("Bvin")
            sb.Append(vbTab)
            sb.Append("ParentId")
            sb.Append(vbTab)
            sb.Append("Status")
            sb.Append(vbTab)
            sb.Append("Sku")
            sb.Append(vbTab)
            sb.Append("ProductName")
            sb.Append(vbTab)
            sb.Append("ProductTypeId")
            sb.Append(vbTab)
            sb.Append("SitePrice")
            sb.Append(vbTab)
            sb.Append("SitePriceOverrideText")
            sb.Append(vbTab)
            sb.Append("ListPrice")
            sb.Append(vbTab)
            sb.Append("SiteCost")
            sb.Append(vbTab)
            sb.Append("ShortDescription")
            sb.Append(vbTab)
            sb.Append("LongDescription")
            sb.Append(vbTab)
            sb.Append("ImageFileSmall")
            sb.Append(vbTab)
            sb.Append("ImageFileMedium")
            sb.Append(vbTab)
            sb.Append("AdditionalImages")
            sb.Append(vbTab)
            sb.Append("Categories")
            sb.Append(vbTab)
            sb.Append("Keywords")
            sb.Append(vbTab)
            sb.Append("MetaTitle")
            sb.Append(vbTab)
            sb.Append("MetaDescription")
            sb.Append(vbTab)
            sb.Append("MetaKeywords")
            sb.Append(vbTab)
            sb.Append("ManufacturerId")
            sb.Append(vbTab)
            sb.Append("VendorId")
            sb.Append(vbTab)
            sb.Append("RewriteUrl")
            sb.Append(vbTab)
            sb.Append("MinimumQty")
            sb.Append(vbTab)
            sb.Append("PostContentColumnId")
            sb.Append(vbTab)
            sb.Append("PreContentColumnId")
            sb.Append(vbTab)
            sb.Append("PreTransformLongDescription")
            sb.Append(vbTab)
            sb.Append("NonShipping")
            sb.Append(vbTab)
            sb.Append("ShippingHeight")
            sb.Append(vbTab)
            sb.Append("ShippingLength")
            sb.Append(vbTab)
            sb.Append("ShippingMode")
            sb.Append(vbTab)
            sb.Append("ShippingWeight")
            sb.Append(vbTab)
            sb.Append("ShippingWidth")
            sb.Append(vbTab)
            sb.Append("ShipSeparately")
            sb.Append(vbTab)
            sb.Append("ExtraShipFee")
            sb.Append(vbTab)
            sb.Append("SpecialProductType")
            sb.Append(vbTab)
            sb.Append("TaxClass")
            sb.Append(vbTab)
            sb.Append("TaxExempt")
            sb.Append(vbTab)
            sb.Append("TemplateName")
            sb.Append(vbTab)
            sb.Append("TrackInventory")
            sb.Append(vbTab)
            sb.Append("CreationDate")
            sb.Append(vbTab)
            sb.Append("LastUpdated")
            sb.Append(System.Environment.NewLine)

        End Sub

        Private Sub WriteItem(ByVal p As BVweb.Product, ByRef sb As StringBuilder, ByRef t As BVweb.AuthenticationToken, ByRef svc As BVweb.WebServices3)

            ' Load Product Here so we get images and categories
            p = svc.Catalog_InternalProduct_FindByBvin(t, p.Bvin)

            sb.Append(p.Bvin)
            sb.Append(vbTab)
            sb.Append(p.ParentId)
            sb.Append(vbTab)
            sb.Append(SafeStatus(p.Status))
            sb.Append(vbTab)
            sb.Append(SafeString(p.Sku))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ProductName))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ProductTypeId))
            sb.Append(vbTab)
            sb.Append(SafeString(p.SitePrice.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.SitePriceOverrideText))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ListPrice.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.SiteCost.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ShortDescription))
            sb.Append(vbTab)
            sb.Append(SafeString(p.LongDescription))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ImageFileSmall))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ImageFileMedium))
            sb.Append(vbTab)


            sb.Append(SafeImages(p.AdditionalImages))
            sb.Append(vbTab)
            sb.Append(SafeCategories(p.Categories))
            sb.Append(vbTab)

            sb.Append(SafeString(p.Keywords))
            sb.Append(vbTab)
            sb.Append(SafeString(p.MetaTitle))
            sb.Append(vbTab)
            sb.Append(SafeString(p.MetaDescription))
            sb.Append(vbTab)
            sb.Append(SafeString(p.MetaKeywords))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ManufacturerId))
            sb.Append(vbTab)
            sb.Append(SafeString(p.VendorId))
            sb.Append(vbTab)
            sb.Append(SafeString(p.RewriteUrl))
            sb.Append(vbTab)
            sb.Append(SafeString(p.MinimumQty))
            sb.Append(vbTab)
            sb.Append(SafeString(p.PostContentColumnId))
            sb.Append(vbTab)
            sb.Append(SafeString(p.PreContentColumnId))
            sb.Append(vbTab)
            sb.Append(SafeString(p.PreTransformLongDescription))
            sb.Append(vbTab)
            sb.Append(SafeBool(p.NonShipping))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ShippingHeight.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ShippingLength.ToString))
            sb.Append(vbTab)
            sb.Append(SafeShippingMode(p.ShippingMode))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ShippingWeight.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ShippingWidth.ToString))
            sb.Append(vbTab)
            sb.Append(SafeBool(p.ShipSeparately))
            sb.Append(vbTab)
            sb.Append(SafeString(p.ExtraShipFee.ToString))
            sb.Append(vbTab)
            sb.Append(SafeSpecialProductType(p.SpecialProductType))
            sb.Append(vbTab)
            sb.Append(SafeString(p.TaxClass))
            sb.Append(vbTab)
            sb.Append(SafeBool(p.TaxExempt))
            sb.Append(vbTab)
            sb.Append(SafeString(p.TemplateName))
            sb.Append(vbTab)
            sb.Append(SafeBool(p.TrackInventory))
            sb.Append(vbTab)
            sb.Append(SafeString(p.CreationDate.ToString))
            sb.Append(vbTab)
            sb.Append(SafeString(p.LastUpdated))

            sb.Append(System.Environment.NewLine)
        End Sub

        Private Function SafeString(ByVal input As String) As String
            Dim result As String = input.Replace(vbTab, "")
            result = result.Replace(vbNewLine, "")
            result = result.Replace(vbCr, "")
            result = result.Replace(vbLf, "")
            Return result
        End Function

        Private Function SafeBool(ByVal input As Boolean) As String
            If input = True Then
                Return "True"
            Else
                Return "False"
            End If
        End Function

        Private Function SafeDecimal(ByVal input As String) As Decimal
            Dim result As Decimal = 0
            Decimal.TryParse(input, result)
            Return result
        End Function

        Private Function SafeStatus(ByVal s As BVweb.ProductStatus) As String
            Dim result As String = "Unknown"
            Select Case s
                Case BVweb.ProductStatus.Active
                    result = "Active"
                Case BVweb.ProductStatus.Disabled
                    result = "Disabled"
                Case BVweb.ProductStatus.NotSet
                    result = "Unknown"
            End Select
            Return result
        End Function

        Private Function SafeCategories(ByVal cats() As String) As String
            Dim result As String = String.Empty
            If cats IsNot Nothing Then
                For i As Integer = 0 To cats.Length - 1
                    result = result & cats(i)
                    If i < cats.Length - 1 Then
                        result = result & ","
                    End If
                Next
            End If
            Return result
        End Function

        Private Function SafeShippingMode(ByVal s As BVweb.ShippingMode) As String
            Dim result As String = "Uknown"
            Select Case s
                Case BVweb.ShippingMode.None
                    result = "Uknown"
                Case BVweb.ShippingMode.ShipFromManufacturer
                    result = "Manufacturer"
                Case BVweb.ShippingMode.ShipFromSite
                    result = "Site"
                Case BVweb.ShippingMode.ShipFromVendor
                    result = "Vendor"
            End Select
            Return result
        End Function

        Private Function SafeSpecialProductType(ByVal s As BVweb.SpecialProductTypes) As String
            Dim result As String = "Normal"
            Select Case s
                Case BVweb.SpecialProductTypes.ArbitrarilyPricedGiftCertificate
                    result = "VariableGift"
                Case BVweb.SpecialProductTypes.GiftCertificate
                    result = "Gift"
                Case BVweb.SpecialProductTypes.Normal
                    result = "Normal"
            End Select
            Return result
        End Function

        Private Function SafeImages(ByVal img() As BVweb.ProductImage) As String
            Dim result As String = String.Empty
            If img IsNot Nothing Then
                For i As Integer = 0 To img.Length - 1
                    Dim tempImage As New ProductImageData(img(i))
                    result = SafeString(tempImage.ToString())
                    'result = result & img(i).Bvin & "^" & SafeString(img(i).FileName) & "^" & SafeString(img(i).AlternateText) & "^" & SafeString(img(i).Caption)
                    If i < img.Length - 1 Then
                        result = result & "|"
                    End If
                Next
            End If
            Return result
        End Function

        Private Function ScrubSku(ByVal input As String) As String
            Dim result As String = input

            result = result.Replace(" ", "")
            result = result.Replace("""", "")
            result = result.Replace("?", "")
            result = result.Replace("=", "")
            result = result.Replace("/", "")
            result = result.Replace("\", "")
            result = result.Replace("%", "")
            result = result.Replace("#", "")
            result = result.Replace("*", "")
            result = result.Replace("!", "")
            result = result.Replace("$", "")
            result = result.Replace("&", "")
            result = result.Replace("+", "")
            result = result.Replace(",", "")
            result = result.Replace("@", "")
            result = result.Replace(":", "")
            result = result.Replace(";", "")
            result = result.Replace(">", "")
            result = result.Replace("<", "")
            result = result.Replace("{", "")
            result = result.Replace("}", "")
            result = result.Replace("~", "")
            result = result.Replace("|", "")
            result = result.Replace("^", "")
            result = result.Replace("[", "")
            result = result.Replace("]", "")
            result = result.Replace("`", "")
            result = result.Replace("'", "")

            result = result.ToUpper

            Return result
        End Function

    End Class

End Namespace